#pragma once
#ifndef IMAGE2D_API
#ifdef WIN32
#define IMAGE2D_API __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#  define IMAGE2D_API __attribute__ ((visibility ("default")))
#else
#define IMAGE2D_API
#endif
#endif

#include <string>
#include <memory>

namespace Image2D {

enum class  ImageFormat
{
    IMAGE_NONE    = 0,
    IMAGE_YUV420p = 1,
    IMAGE_NV12    = 2,
    IMAGE_RGB     = 3,
    IMAGE_BGR     = 4,
    IMAGE_RGBA    = 5,
    IMAGE_BGRA    = 6,
};

enum class ImageType
{
    IMAGE_CHAR            = 0,
    IMAGE_SHORT           = 1,
    IMAGE_INT             = 2,
    IMAGE_FLOAT           = 3,
    IMAGE_DOUBLE          = 4,

    IMAGE_UNSIGNED_CHAR   = 5,
    IMAGE_UNSIGNED_SHORT  = 6,
    IMAGE_UNSIGNED_INT    = 7,
};

class Image2D_Imp;
class Image2D_Ptr
{
private:
    std::shared_ptr<Image2D_Imp> m_image2d;

public:
    IMAGE2D_API Image2D_Ptr();
    IMAGE2D_API Image2D_Ptr(const Image2D_Ptr& i2d);
    IMAGE2D_API Image2D_Ptr(int width, int height, ImageFormat format = ImageFormat::IMAGE_NV12, ImageType type = ImageType::IMAGE_UNSIGNED_CHAR);
    IMAGE2D_API Image2D_Ptr(const void** data, const size_t* linesize, int width, int height, ImageFormat format, ImageType type);
    IMAGE2D_API ~Image2D_Ptr();

    IMAGE2D_API int           width()             const;
    IMAGE2D_API int           height()            const;
    IMAGE2D_API const void**  data()              const;
    IMAGE2D_API const void*   data(int index)     const;
    IMAGE2D_API const size_t* linesize()          const;
    IMAGE2D_API size_t        linesize(int index) const;
    IMAGE2D_API ImageFormat   format()            const;
    IMAGE2D_API ImageType     type()              const;
    IMAGE2D_API int           typeSize()          const;

    IMAGE2D_API static int           lastErrorCode();
    IMAGE2D_API static std::string   lastErrorStr();
};

    IMAGE2D_API  int           lastErrorCode();
    IMAGE2D_API  std::string   lastErrorStr();

}